package com.mou.service.impl;

import com.mou.dto.ProductSearchDTO;
import com.mou.es.ProductDocument;
import com.mou.es.ProductEsRepository;
import com.mou.service.ProductEsService;
import com.mou.vo.ProductVO;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.stream.Collectors;

@Service("productEsService")
@Slf4j
public class ProductEsServiceImpl implements ProductEsService {
    @Autowired
    private ElasticsearchRestTemplate esTemplate;

    @Autowired
    private ProductEsRepository productEsRepository;

    /**
     * 不分页：一次性返回所有匹配结果（size 设置为 10000，适合 total ≤ 10000）
     */
    public List<ProductVO> search(ProductSearchDTO dto) {
        NativeSearchQueryBuilder qb = new NativeSearchQueryBuilder();

        // 关键字查询（title & description）
        if (dto != null && dto.getKeyword() != null && !dto.getKeyword().trim().isEmpty()) {
            qb.withQuery(QueryBuilders.multiMatchQuery(dto.getKeyword(), "title", "description"));
            qb.withHighlightBuilder(new HighlightBuilder()
                    .field("title").field("description")
                    .preTags("<em>").postTags("</em>"));
        } else {
            qb.withQuery(QueryBuilders.matchAllQuery());
        }

        // 固定条件：status = 0, deleted = 0（和你 DB 查询一致）
        qb.withFilter(QueryBuilders.termQuery("status", 0));
        qb.withFilter(QueryBuilders.termQuery("deleted", 0));

        // 分类过滤（若传了 categoryId）
        if (dto != null && dto.getCategoryId() != null) {
            qb.withFilter(QueryBuilders.termQuery("categoryId", dto.getCategoryId()));
        }

        // 关键：一次性返回的数量（注意 ES 默认 max_result_window 通常 10000）
        qb.withPageable(PageRequest.of(0, 10000));

        NativeSearchQuery query = qb.build();

        SearchHits<ProductDocument> hits = esTemplate.search(query, ProductDocument.class);

        List<ProductVO> list = hits.getSearchHits().stream()
                .map(this::hitToVO)
                .collect(Collectors.toList());

        return list;
    }

    private ProductVO hitToVO(SearchHit<ProductDocument> hit) {
        ProductDocument d = hit.getContent();
        ProductVO vo = new ProductVO();
        if (d == null) return vo;

        vo.setId(d.getId());
        vo.setTitle(d.getTitle());
        vo.setDescription(d.getDescription());
        vo.setPrice(d.getPrice());
        vo.setCategoryId(d.getCategoryId());
        vo.setStatus(d.getStatus());
        vo.setIsCarousel(d.getIsCarousel());
        vo.setSellerId(d.getSellerId());
        vo.setImageUrl(d.getImageUrl());
        vo.setCreateTime(d.getCreateTime());
        vo.setUpdateTime(d.getUpdateTime());
        vo.setDeleted(d.getDeleted());

        // 高亮替换（若存在）
        if (hit.getHighlightFields() != null && !hit.getHighlightFields().isEmpty()) {
            List<String> titleHl = hit.getHighlightFields().get("title");
            if (titleHl != null && !titleHl.isEmpty()) {
                vo.setTitle(titleHl.get(0));
            }
            List<String> descHl = hit.getHighlightFields().get("description");
            if (descHl != null && !descHl.isEmpty()) {
                vo.setDescription(descHl.get(0));
            }
        }
        return vo;
    }

    // 单条索引（新增/更新 DB 后调用）
    public void indexProduct(ProductDocument doc) {
        if (doc == null) return;
        productEsRepository.save(doc);
    }

    public void deleteById(Integer id) {
        productEsRepository.deleteById(id);
    }

    // 启动时确保索引存在（若 ES 未启动，会在日志中提示）
    @PostConstruct
    public void ensureIndex() {
        try {
            if (!esTemplate.indexOps(ProductDocument.class).exists()) {
                esTemplate.indexOps(ProductDocument.class).create();
                esTemplate.indexOps(ProductDocument.class).putMapping(esTemplate.indexOps(ProductDocument.class).createMapping());
            }
        } catch (Exception e) {
            log.warn("检查/创建 ES 索引失败（可能 ES 未启动）: {}", e.getMessage());
        }
    }
}
